﻿using IOA.MES.Client.Common;
using IOA.MES.Client.Models.Response;
using IOA.MES.Client.Settings;
using NLog;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;
using IOA.MES.Client.Models;
using Newtonsoft.Json;

namespace IOA.MES.Client.InsulatedResistance
{
    /// <summary>
    /// WithstandVoltageIndex.xaml 的交互逻辑
    /// </summary>
    public partial class InsulatedResistanceIndex : Window
    {
        private List<ViaSiteRecord> records { get; set; } = new List<ViaSiteRecord>();
        private FileSystemWatcher dataFileWatcher;

        public InsulatedResistanceIndex()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var folder = BaseEnv.GetStorage("InsulatedResistanceMonitorFile");
            if (Directory.Exists(folder))
            {
                txtFolder.Text = folder;
                WatcherStrat(folder);
            }
            txtTrueName.Content = BaseEnv.UserInfo.TrueName;
            InitDuties();
            InitMachines();
            InitRecords();
        }

        #region 初始化数据
        public void InitDuties()
        {
            var duties = BaseEnv.InvokeApi<QueryDutiesResponse>("/api/Auth/QueryDuties", new { WorkshopCode = BaseEnv.WorkshopCode }).Data.Duties;

            cbDuties.ItemsSource = duties;
            cbDuties.DisplayMemberPath = "DutyName";
            cbDuties.SelectedValuePath = "DutyId";

            if (duties.Any())
            {
                cbDuties.SelectedIndex = 0;
            }
        }

        public void InitMachines()
        {
            var machines = BaseEnv.InvokeApi<QueryMachinesResponse>("/api/Machine/QueryMachines", new { WorkshopCode = BaseEnv.WorkshopCode, MachineType = (int)MachineType.WithstandVoltage }).Data.Machines;
            cbMachines.ItemsSource = machines;
            cbMachines.DisplayMemberPath = "MachineName";
            cbMachines.SelectedValuePath = "MachineId";

            if (machines.Any(_ => _.MachineId == BaseEnv.MachineId))
            {
                cbMachines.SelectedIndex = machines.FindIndex(_ => _.MachineId == BaseEnv.MachineId);
            }
            else
            {
                CommonMessage.Alert(this, "请先在系统设置中重新选择设备\r\nPlease reselect the device in the system settings now"); ;
                new SettingsIndex().ShowDialog();
            }
        }

        private void InitRecords()
        {
            new TaskFactory().StartNew(() =>
            {
                Thread.Sleep(100);
                Dispatcher.Invoke(new Action(() =>
                {
                    var response = BaseEnv.InvokeApi<QueryViaSiteRecordsResponse>("/api/Machine/QueryViaSiteRecords", new { DutyId = Convert.ToInt32(cbDuties.SelectedValue), SiteType = SiteType.InsulatedResistance, MachineId = Convert.ToInt32(cbMachines.SelectedValue) });
                    if (response.ErrCode != 200)
                    {
                        CommonMessage.Alert(this, response.ErrMsg);
                        return;
                    }
                    records.Clear();
                    records.AddRange(response.Data.Records);
                    records.ForEach(_ => _.No = records.Count - records.IndexOf(_));
                    BindGridRecords();
                }));
            });
        }

        private void BindGridRecords()
        {
            gridRecords.ItemsSource = null;
            gridRecords.ItemsSource = records;
            lbTotal.Content = records.Select(_ => _.Code.ToUpper().Trim()).Distinct().Count();
        }
        #endregion

        private void cb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            InitRecords();
        }

        private void btnSelectFile_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var dialog = new FolderBrowserDialog();
                if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK && Directory.Exists(dialog.SelectedPath))
                {
                    txtFolder.Text = dialog.SelectedPath;
                    BaseEnv.SetStorage("InsulatedResistanceMonitorFile", dialog.SelectedPath);
                    WatcherStrat(dialog.SelectedPath);
                }
            }
            catch (Exception ex)
            {
                CommonMessage.Alert(this, ex.ToString());
            }
        }


        private void WatcherStrat(string folder)
        {
            dataFileWatcher = new FileSystemWatcher(folder);
            dataFileWatcher.Changed += Watcher_Changed;
            dataFileWatcher.IncludeSubdirectories = true;
            dataFileWatcher.EnableRaisingEvents = true;
            dataFileWatcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess
                                   | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;
            dataFileWatcher.IncludeSubdirectories = true;
        }

        private void Watcher_Changed(object sender, FileSystemEventArgs e)
        {
            if (!string.Equals(Path.GetExtension(e.FullPath), ".mdb", StringComparison.CurrentCultureIgnoreCase))
            {
                return;
            }
            var insulateData = GetLastData(e.FullPath);
            if (insulateData == null)
            {
                return;
            }
            else if (string.IsNullOrWhiteSpace(insulateData.BarCode))
            {
                CommonMessage.Log(LogLevel.Warn, $"数据条码为空：{JsonConvert.SerializeObject(insulateData)}");
                return;
            }

            new TaskFactory().StartNew(() =>
            {
                ViaSite(insulateData);
            });
        }

        private void ViaSite(InsulateData insulateData)
        {
            dynamic viaSiteRequest = null;
            Dispatcher.Invoke(new Action(() =>
            {
                viaSiteRequest = new
                {
                    SiteType = SiteType.InsulatedResistance,
                    DutyId = Convert.ToInt32(cbDuties.SelectedValue),
                    MachineId = Convert.ToInt32(cbMachines.SelectedValue),
                    Code = insulateData.BarCode,
                    InsulateData = insulateData,
                    Images = new List<string>()
                };
            }));

            var response = BaseEnv.InvokeApi<ViaSiteResponse>("/api/Machine/ViaSite", viaSiteRequest);
            Dispatcher.Invoke(new Action(() =>
            {
                if (response.ErrCode != 200)
                {
                    mediaElResult.Source = new Uri($"{BaseEnv.LocalDirectory}\\res\\audio\\Fail.wav");
                    mediaElResult.Play();
                    CommonMessage.Alert(this, response.ErrMsg, false);
                    return;
                }
                CommonMessage.Log(LogLevel.Info, $"过站成功：{viaSiteRequest.Code.Trim()}");

                mediaElResult.Source = new Uri($"{BaseEnv.LocalDirectory}\\res\\audio\\Success.wav");
                mediaElResult.Play();

                txtWorkOrderNo.Text = response.Data.ViaSiteRecord.WorkOrderNo;

                if (response.Data.DutyId != Convert.ToInt32(cbDuties.SelectedValue))
                {
                    cbDuties.SelectedValue = response.Data.DutyId;
                }
                else
                {
                    response.Data.ViaSiteRecord.No = records.Count + 1;
                    records.Insert(0, response.Data.ViaSiteRecord);
                    BindGridRecords();
                }
            }));
        }

        private InsulateData GetLastData(string fileName)
        {
            var datas = new List<InsulateData>();
            var dt = GetMdbData(fileName, "SELECT TOP 1 * FROM ALLlist ORDER BY id DESC");
            if (dt.Rows.Count <= 0)
            {
                return null;
            }
            else
            {
                var dr = dt.Rows[0];
                return new InsulateData
                {
                    BarCode = Convert.ToString(dr["条码值"])?.Trim() ?? string.Empty,
                    Position = Convert.ToString(dr["工位"])?.Trim() ?? string.Empty,
                    StartTime = Convert.ToString(dr["开始时间"])?.Trim() ?? string.Empty,
                    EndTime = Convert.ToString(dr["结束时间"])?.Trim() ?? string.Empty,
                    TestDuring = Convert.ToString(dr["总耗时"])?.Trim() ?? string.Empty,
                    Param1 = Convert.ToString(dr["M1测试项"])?.Trim() ?? string.Empty,
                    Param1Setting1 = Convert.ToString(dr["M1设置1值"])?.Trim() ?? string.Empty,
                    Param1Test1 = Convert.ToString(dr["M1测试1值"])?.Trim() ?? string.Empty,
                    Param1Test2 = Convert.ToString(dr["M1测试2值"])?.Trim() ?? string.Empty,
                    Param1Test2Max = Convert.ToString(dr["M1设置2值上限"])?.Trim() ?? string.Empty,
                    Param1Test2Min = Convert.ToString(dr["M1设置2值下限"])?.Trim() ?? string.Empty,
                    Param1Result = Convert.ToString(dr["M1测试结果"])?.Trim() ?? string.Empty,
                    Param2 = Convert.ToString(dr["M2测试项"])?.Trim() ?? string.Empty,
                    Param2Setting1 = Convert.ToString(dr["M2设置1值"])?.Trim() ?? string.Empty,
                    Param2Test1 = Convert.ToString(dr["M2测试1值"])?.Trim() ?? string.Empty,
                    Param2Test2 = Convert.ToString(dr["M2测试2值"])?.Trim() ?? string.Empty,
                    Param2Test2Max = Convert.ToString(dr["M2设置2值上限"])?.Trim() ?? string.Empty,
                    Param2Test2Min = Convert.ToString(dr["M2设置2值下限"])?.Trim() ?? string.Empty,
                    Param2Result = Convert.ToString(dr["M2测试结果"])?.Trim() ?? string.Empty,
                    Param3 = Convert.ToString(dr["M3测试项"])?.Trim() ?? string.Empty,
                    Param3Setting1 = Convert.ToString(dr["M3设置1值"])?.Trim() ?? string.Empty,
                    Param3Test1 = Convert.ToString(dr["M3测试1值"])?.Trim() ?? string.Empty,
                    Param3Test2 = Convert.ToString(dr["M3测试2值"])?.Trim() ?? string.Empty,
                    Param3Test2Max = Convert.ToString(dr["M3设置2值上限"])?.Trim() ?? string.Empty,
                    Param3Test2Min = Convert.ToString(dr["M3设置2值下限"])?.Trim() ?? string.Empty,
                    Param3Result = Convert.ToString(dr["M3测试结果"])?.Trim() ?? string.Empty,
                    Param4 = Convert.ToString(dr["M4测试项"])?.Trim() ?? string.Empty,
                    Param4Setting1 = Convert.ToString(dr["M4设置1值"])?.Trim() ?? string.Empty,
                    Param4Test1 = Convert.ToString(dr["M4测试1值"])?.Trim() ?? string.Empty,
                    Param4Test2 = Convert.ToString(dr["M4测试2值"])?.Trim() ?? string.Empty,
                    Param4Test2Max = Convert.ToString(dr["M4设置2值上限"])?.Trim() ?? string.Empty,
                    Param4Test2Min = Convert.ToString(dr["M4设置2值下限"])?.Trim() ?? string.Empty,
                    Param4Result = Convert.ToString(dr["M4测试结果"])?.Trim() ?? string.Empty,
                    Result = Convert.ToString(dr["总结果"])?.Trim() ?? string.Empty,
                };
            }
        }

        private object lockObj = new object();
        private DataTable GetMdbData(string fileName, string sql)
        {
            DataTable dt = new DataTable();
            try
            {
                Thread.Sleep(2000);
                lock (lockObj)
                {
                    var conn = new OleDbConnection($"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={fileName}");
                    conn.Open();
                    var cmd = conn.CreateCommand();
                    cmd.CommandText = sql;
                    var dr = cmd.ExecuteReader();
                    if (dr.HasRows)
                    {
                        for (int i = 0; i < dr.FieldCount; i++)
                        {
                            dt.Columns.Add(dr.GetName(i));
                        }
                        dt.Rows.Clear();
                    }
                    while (dr.Read())
                    {
                        DataRow row = dt.NewRow();
                        for (int i = 0; i < dr.FieldCount; i++)
                        {
                            row[i] = dr[i];
                        }
                        dt.Rows.Add(row);
                    }
                    cmd.Dispose();
                    conn.Close();
                }
            }
            catch (Exception ex)
            {
                CommonMessage.Alert(this, $"读取Access出错\r\nError reading Access：\r\n{ex.ToString()}", false);
            }
            return dt;
        }

        private void Menu_Click(object sender, RoutedEventArgs e)
        {
            switch (((System.Windows.Controls.MenuItem)sender).Name)
            {
                case "btnSettings":
                    new SettingsIndex().ShowDialog();
                    break;
                case "btnMissingRecords":
                    new MissingSiteRecord(Convert.ToInt32(cbMachines.SelectedValue)).Show();
                    break;
                case "btnLogout":
                    new LoginWindow(false).Show();
                    this.Hide();
                    break;
                case "btnAbout":
                    System.Windows.MessageBox.Show($"AISUNMes Product Version:{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion}");
                    break;
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
        }
    }
}
